package org.lanyu.springainovel.novel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import org.lanyu.springainovel.novel.entity.BookOutline;
import org.lanyu.springainovel.novel.entity.BookRole;
import org.lanyu.springainovel.novel.mapper.BookRoleMapper;
import org.lanyu.springainovel.novel.service.BookRoleService;
import org.lanyu.springainovel.novel.service.NovelOutlineService;
import org.lanyu.springainovel.common.service.StreamGenerationService;
import org.lanyu.springainovel.common.dto.StreamGenerationRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 人设服务实现类
 */
@Slf4j
@Service
public class BookRoleServiceImpl extends ServiceImpl<BookRoleMapper, BookRole> implements BookRoleService {

    @Autowired
    private NovelOutlineService novelOutlineService;

    @Autowired
    private StreamGenerationService streamGenerationService;


    @Override
    public BookRole getCharacterProfilesByBookIdAndVersion(Long bookId,Long version) {
        QueryWrapper<BookRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        if (version != null) {
            queryWrapper.eq("version", version);
        } else {
            queryWrapper.orderByDesc("version");
            queryWrapper.last("LIMIT 1");
        }
        return this.getOne(queryWrapper);
    }

    @Override
    public BookRole getLatestCharacterProfile(Long bookId) {
        QueryWrapper<BookRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.orderByDesc("version");
        queryWrapper.last("LIMIT 1");
        return this.getOne(queryWrapper);
    }

    /**
     * 获取当前启用状态的角色
     * @param bookId 书籍ID
     * @return 当前启用状态的角色，如果没有则返回null
     */
    public BookRole getActiveCharacterProfile(Long bookId) {
        QueryWrapper<BookRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.eq("is_active", 1);
        return this.getOne(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookRole addCharacterProfile(BookRole bookRole) {
        // 获取当前最新版本
        BookRole latestProfile = getLatestCharacterProfile(bookRole.getBookId());
        int nextVersion = (latestProfile != null) ? latestProfile.getVersion() + 1 : 1;

        // 新建小说人设时，提供模板人设JSON
        String characterProfileJson = "[\n" +
                "  {\n" +
                "    \"姓名\": \"角色名称1\",\n" +
                "    \"派系\": \"角色所属派系1\",\n" +
                "    \"外在特征\": \"外貌、穿着、体态、行为习惯等外部特征描述\",\n" +
                "    \"内在特征\": \"性格、价值观、信念、目标等内部特征描述\",\n" +
                "    \"社会特征\": \"社会地位、职业、人际关系等社会特征描述\",\n" +
                "    \"成长弧光\": \"角色成长变化轨迹描述\",\n" +
                "    \"作用\": \"角色在故事中的作用\"\n" +
                "  }\n" +
                "]";

        // 设置书籍ID和版本号
        bookRole.setVersion(nextVersion);
        bookRole.setCharacterProfile(characterProfileJson);
        bookRole.setCreateTime(LocalDateTime.now());
        bookRole.setUpdateTime(LocalDateTime.now());
        //新建人设时还没有角色信息，默认不启用
        bookRole.setIsActive(0);
        bookRole.setRemark("人设版本v"+nextVersion);

        // 保存人设
        this.save(bookRole);

        return bookRole;
    }

    @Override
    public boolean deleteCharacterProfileByBookIdAndVersion(Long bookId, Long version) {
        QueryWrapper<BookRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.eq("version", version);
        return this.remove(queryWrapper);
    }

    @Override
    public List<BookRole> getCharacterProfileVersions(Long bookId) {
        QueryWrapper<BookRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.orderByDesc("version");
        return this.list(queryWrapper);
    }

    @Override
    public Map<String, Integer> getFactionStatistics(Long bookId) {
        // 获取最新版本的人设
        BookRole profile = getLatestCharacterProfile(bookId);
        Map<String, Integer> statistics = new HashMap<>();

        if (profile != null && StringUtils.hasText(profile.getCharacterProfile())) {
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                List<Map<String, Object>> profiles = objectMapper.readValue(
                    profile.getCharacterProfile(),
                    new TypeReference<List<Map<String, Object>>>() {}
                );

                // 按派系分组统计
                for (Map<String, Object> character : profiles) {
                    String faction = (String) character.getOrDefault("派系", "未分类");
                    if (!StringUtils.hasText(faction)) {
                        faction = "未分类";
                    }
                    statistics.put(faction, statistics.getOrDefault(faction, 0) + 1);
                }
            } catch (JsonProcessingException e) {
            log.error("解析人设JSON失败，无法统计派系", e);
        }
        }

        return statistics;
    }


    @Override
    public Flux<String> batchGenerateCharacterProfilesStream(StreamGenerationRequest request) {
        try {
            // 从请求中获取书籍ID
            Long bookId = request.getBookId();
            if (bookId == null) {
                return Flux.error(new RuntimeException("书籍ID不能为空"));
            }

            // 查询最新版本的大纲信息
            BookOutline outlineContent = novelOutlineService.getOutlineByBookId(bookId);
            if (outlineContent == null) {
                return Flux.error(new RuntimeException("未找到书籍大纲信息，请先创建大纲"));
            }

            // 构建新的用户提示词，将大纲信息作为上下文
            String originalUserPrompt = request.getUserPrompt();
            String enhancedUserPrompt = String.format(
                    "书籍大纲：\n%s \n%s",
                    outlineContent.getOutlineDetails(),
                    originalUserPrompt
            );

            // 创建新的请求对象，使用增强后的用户提示词
            StreamGenerationRequest enhancedRequest = new StreamGenerationRequest();
            enhancedRequest.setModelId(request.getModelId());
            enhancedRequest.setUserPrompt(enhancedUserPrompt);
            enhancedRequest.setSystemPromptId(request.getSystemPromptId());
            enhancedRequest.setBookId(bookId);
            enhancedRequest.setBusiness(request.getBusiness());
            enhancedRequest.setAbortSignal(request.getAbortSignal());

            // 调用StreamGenerationService生成流式响应
            return streamGenerationService.generateStreamResponse(enhancedRequest);

        } catch (Exception e) {
            log.error("批量生成角色流式响应失败", e);
            return Flux.error(new RuntimeException("生成角色失败: " + e.getMessage()));
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookRole updateCharacterProfileByVersion(BookRole bookRole) {
        // 参数校验
        if (bookRole.getBookId() == null) {
            throw new IllegalArgumentException("书籍ID不能为空");
        }
        if (bookRole.getVersion() == null || bookRole.getVersion() <= 0) {
            throw new IllegalArgumentException("版本号必须为正整数");
        }
        
        // 查询指定版本的人设
        QueryWrapper<BookRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookRole.getBookId());
        queryWrapper.eq("version", bookRole.getVersion());
        BookRole existingProfile = this.getOne(queryWrapper);
        
        if (existingProfile == null) {
            throw new RuntimeException("未找到书籍ID为" + bookRole.getBookId() + "版本号为" + bookRole.getVersion() + "的人设信息");
        }

        // 更新人设信息
        if (StrUtil.isNotBlank(bookRole.getCharacterProfile())) {
            existingProfile.setCharacterProfile(bookRole.getCharacterProfile());
        }

        if (StringUtils.hasText(bookRole.getRemark())) {
            existingProfile.setRemark(bookRole.getRemark());
        }
        
        // 处理isActive字段
        if (bookRole.getIsActive() != null) {
            // 如果要设置为启用状态，需要先将同一本书的所有角色设置为非启用状态
            if (bookRole.getIsActive() == 1 && (existingProfile.getIsActive() == null || existingProfile.getIsActive() != 1)) {
                QueryWrapper<BookRole> updateWrapper = new QueryWrapper<>();
                updateWrapper.eq("book_id", bookRole.getBookId());
                BookRole updateRole = new BookRole();
                updateRole.setIsActive(0);
                this.update(updateRole, updateWrapper);
            }
            existingProfile.setIsActive(bookRole.getIsActive());
        }
        
        existingProfile.setUpdateTime(LocalDateTime.now());
        
        // 保存更新
        this.updateById(existingProfile);
        
        log.info("成功更新书籍ID为{}版本号为{}的人设信息", bookRole.getBookId(), bookRole.getVersion());
        
        return existingProfile;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BookRole archiveCharacterProfile(BookRole bookRole) {
        // 参数校验
        if (bookRole.getBookId() == null) {
            throw new IllegalArgumentException("书籍ID不能为空");
        }
        if (bookRole.getVersion() == null || bookRole.getVersion() <= 0) {
            throw new IllegalArgumentException("版本号必须为正整数");
        }
        
        // 查询要归档的版本人设
        QueryWrapper<BookRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookRole.getBookId());
        queryWrapper.eq("version", bookRole.getVersion());
        BookRole sourceProfile = this.getOne(queryWrapper);
        
        if (sourceProfile == null) {
            throw new RuntimeException("未找到书籍ID为" + bookRole.getBookId() + "版本号为" + bookRole.getVersion() + "的人设信息");
        }
        
        // 获取当前最大版本号
        QueryWrapper<BookRole> maxVersionWrapper = new QueryWrapper<>();
        maxVersionWrapper.eq("book_id", bookRole.getBookId());
        maxVersionWrapper.select("MAX(version) as version");
        List<Map<String, Object>> result = this.listMaps(maxVersionWrapper);
        
        int maxVersion = 0;
        if (!result.isEmpty() && result.get(0).get("version") != null) {
            maxVersion = (Integer) result.get(0).get("version");
        }
        
        // 创建新记录，版本号为当前最大版本号+1
        BookRole archivedProfile = new BookRole();
        archivedProfile.setBookId(bookRole.getBookId());
        archivedProfile.setCharacterProfile(sourceProfile.getCharacterProfile());
        archivedProfile.setRemark(sourceProfile.getRemark());
        archivedProfile.setVersion(maxVersion + 1);
        archivedProfile.setCreateTime(LocalDateTime.now());
        archivedProfile.setUpdateTime(LocalDateTime.now());
        
        // 归档的角色默认不启用
        archivedProfile.setIsActive(0);
        
        // 保存归档记录
        this.save(archivedProfile);
        
        log.info("成功归档书籍ID为{}版本号为{}的人设信息，新版本号为{}", bookRole.getBookId(), bookRole.getVersion(), archivedProfile.getVersion());
        
        return archivedProfile;
    }
}